package com.smh.demo1.a05;

import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

import java.io.IOException;

/**
 * @author shiminghui
 * @date 2025/4/11 19:46
 * @description: TODO
 */
public class MyMapperScanPostProcessor implements BeanDefinitionRegistryPostProcessor {
    public static void main(String[] args) {
    }

    // 参数传的都是 DefaultListableBeanFactory,只不过接口不同,可以用的方法不同罢了
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        try {
            // 拿到配置类
            MapperScan annotation = AnnotationUtils.findAnnotation(Config.class, MapperScan.class);
            if (annotation != null) {
                String[] strings = annotation.basePackages();
                PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
                CachingMetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
                AnnotationBeanNameGenerator nameGenerator = new AnnotationBeanNameGenerator();
                for (String string : strings) {
                    // 扫描包
                    String s = "classpath*:" + string.replace(".", "/") + "/**/*.class";
                    Resource[] resources = patternResolver.getResources(s);
                    for (Resource resource : resources) {
                        MetadataReader metadataReader = readerFactory.getMetadataReader(resource);
                        // 解析resource,判断是否为接口
                        if (metadataReader.getClassMetadata().isInterface()) {
                            // 用于生成Mapper的一个工厂Bean
                            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class);
                            builder.addConstructorArgValue(metadataReader.getClassMetadata().getClassName()); // 设置构造函数的参数
                            builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
                            AbstractBeanDefinition bd = builder.getBeanDefinition();

                            // 用于生成 beanName
                            AbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();

                            String beanName = nameGenerator.generateBeanName(bd2, beanDefinitionRegistry);
                            beanDefinitionRegistry.registerBeanDefinition(beanName, bd);
                        }
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}
